package P6;

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;

/**
 * 编写一个 ECHO SSL 服务器程序和一个 ECHO SSL 客户端程序，实现以下功能：
 * 1.服务器端监听指定的端口，并等待客户端连接。
 * 2.客户端连接到指定的 SSL 服务器，并建立 SSL 连接。
 * 3.客户端发送一个字符串消息到服务器端，并等待服务器端的响应。
 * 4.服务器端接收客户端发送的消息，并返回一个响应消息。
 * 5.客户端打印服务器端返回的消息，如果客户发送的消息为bye，结束通信，并关闭 SSL 连接。
 * 6.服务器端继续监听并等待下一个客户端连接。
 * 提示：
 * 1.可以使用 Java 标准库中的 SSLServerSocket 和 SSLSocket 类来实现 SSL 服务器和客户端。
 * 2.可以使用 KeyStore 类来加载服务器端证书和私钥，以便进行 SSL 握手认证。
 * 3.可以使用 TrustManager 类来加载客户端证书，以便进行 SSL 握手认证。
 */
public class EchoServer {
    private static final int PORT = 8888;
    private static final String KEYSTORE_PATH = "path/to/keystore.jks";
    private static final String KEYSTORE_PASSWORD = "keystore_password";
    
    public static void main(String[] args) {
        try {
            // 加载密钥库
            KeyStore keyStore = KeyStore.getInstance("JKS");
            FileInputStream fis = new FileInputStream(KEYSTORE_PATH);
            keyStore.load(fis, KEYSTORE_PASSWORD.toCharArray());
            fis.close();
            
            // 创建 SSL 上下文
            SSLContext sslContext = SSLContext.getInstance("TLS");
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
            sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
            
            // 创建 SSL 服务器套接字
            SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory();
            SSLServerSocket serverSocket = (SSLServerSocket) socketFactory.createServerSocket(PORT);
            
            System.out.println("ECHO SSL Server started on port " + PORT);
            
            while (true) {
                // 等待客户端连接
                SSLSocket clientSocket = (SSLSocket) serverSocket.accept();
                System.out.println("Client connected: " + clientSocket.getInetAddress());
                
                // 启动处理客户端请求的线程
                new Thread(() -> handleClient(clientSocket)).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private static void handleClient(SSLSocket clientSocket) {
        try {
            // 启动握手
            clientSocket.startHandshake();
            
            // 创建输入输出流
            InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream();
            
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream), true);
            
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("Received from client: " + line);
                writer.println(line);
            }
            
            // 关闭连接
            clientSocket.close();
            System.out.println("Client disconnected: " + clientSocket.getInetAddress());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


//package P6;
//
//import javax.net.ssl.*;
//import java.io.*;
//import java.net.*;
//import java.nio.ByteBuffer;
//import java.security.KeyStore;
//
//public class EchoServer {
//    private static final int PORT = 8888;
//    private static final String KEYSTORE_PATH = "path/to/keystore.jks";
//    private static final String KEYSTORE_PASSWORD = "keystore_password";
//
//    public static void main(String[] args) {
//        try {
//            // 加载密钥库
//            KeyStore keyStore = KeyStore.getInstance("JKS");
//            FileInputStream fis = new FileInputStream(KEYSTORE_PATH);
//            keyStore.load(fis, KEYSTORE_PASSWORD.toCharArray());
//
//            // 创建 SSL 上下文
//            SSLContext sslContext = SSLContext.getInstance("TLS");
//            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
//            keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
//            sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
//
//            // 创建 SSL 服务器套接字
//            SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory();
//            SSLServerSocket serverSocket = (SSLServerSocket) socketFactory.createServerSocket(PORT);
//
//            System.out.println("ECHO SSL Server started on port " + PORT);
//
//            while (true) {
//                // 等待客户端连接
//                SSLSocket clientSocket = (SSLSocket) serverSocket.accept();
//                System.out.println("Client connected: " + clientSocket.getInetAddress());
//
//                // 启动处理客户端请求的线程
//                new Thread(() -> handleClient(clientSocket)).start();
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    private static void handleClient(SSLSocket clientSocket) {
//        try {
//            // 创建 SSL 引擎
//            SSLEngine sslEngine = clientSocket.getSSLParameters().createSSLEngine();
//            sslEngine.setUseClientMode(false);
//            sslEngine.beginHandshake();
//
//            // 创建 SSL 输入输出流
//            SSLSession sslSession = sslEngine.getSession();
//            InputStream inputStream = clientSocket.getInputStream();
//            OutputStream outputStream = clientSocket.getOutputStream();
//            SSLInputStream sslInputStream = new SSLInputStream(inputStream, sslEngine);
//            SSLOutputStream sslOutputStream = new SSLOutputStream(outputStream, sslEngine);
//
//            ByteBuffer buffer = ByteBuffer.allocate(1024);
//            int bytesRead;
//
//            while ((bytesRead = sslInputStream.read(buffer)) != -1) {
//                buffer.flip();
//                sslOutputStream.write(buffer.array(), 0, bytesRead);
//                buffer.clear();
//            }
//
//            // 关闭连接
//            clientSocket.close();
//            System.out.println("Client disconnected: " + clientSocket.getInetAddress());
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
//}
